﻿using System.Reflection;
using System.Windows.Controls;
using System;
using System.Windows;
using System.Windows.Media.Animation;
using System.Windows.Media;
using System.Collections.Generic;
using HeadLight.Player.Model;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Windows.Resources;
using System.Windows.Input;
using System.ComponentModel;
using Microsoft.Phone.Controls;

namespace NASA.BeAMartian.Views.Explore
{
    public partial class MarsAtlas : PhoneApplicationPage
    {
        public Dictionary<string, string> _regions;
        RegionType _selectedRegion;

        public MarsAtlas()
        {
            InitializeComponent();
            _initParams.Add("adFile", "GeneratedImages");
            _initParams.Add("BaseURL", "http://beamdownload.blob.core.windows.net/media/");
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);

            _regions = new Dictionary<string, string>();
            _regions.Add(RegionType.AcidaliaPlanitia.Description(), "Gateway to the Lowlands||Ahoy!  From your Earth-bound telescope, Acidalia stretches as a dark, smooth plain that astronomers once called a sea.  Perhaps they weren't far off, as Acidalia once stood helpless in the path of floods that poured long ago through the \"Golden Plains\" of Chryse from the \"Mariner Valley\" canyonlands.  Explore it now and you'll see places where ancient shorelines may linger, left from a time when all or part of the north contained lakes or even an ocean.  Do signs of ancient beaches exist?  Controversy reigns among scientists, but go ahead and dream of a long-past ocean.  Just be sure to think of Earth's ice-covered Arctic oceans.  On Mars long ago, such ice would have slowed water's evaporation into the atmosphere, allowing shorelines time to develop.  The whole area is sunken...roughly 10,000 feet below neighboring Arabia Terra!");
            _regions.Add(RegionType.AmazonisPlanitia.Description(), "Legendary Plains of the Warrior Women||Mars may be named after the god of war, but this area pays tribute to the fearless women of the Iliad who \"fought like men.\"   But never fear. If battles were ever waged here by incoming meteors and asteroids, you'd never notice. Lava flows have covered up most traces, with mostly small impact craters remaining here.  The fewer the craters, the younger the surface.  The area thus lends its name to the youngest of three epochs on Mars:  the Amazonian, which began 1.8 billion years ago and continues today.  Want to experience this young, smooth- faced, land here on Earth?  Make your way to Iceland, where a terrain of thick and hardened lava beckons hardy explorers, men and women alike.");
            _regions.Add(RegionType.AoniaTerra.Description(), "Land of the Rippling Dunes||Visit this ancient cratered region, and you're in for a treat.  Here, craters have collected field upon field of sand dunes, which the wind has sculpted into seemingly endless scallops.  That's not all that gives the terrain a softened look.  Left over from the last Ice Age on Mars a few hundred thousand years ago, layers of ice and snow remain to smooth things over.   What keeps the crater bowls filled with ice is a coating of dust on top that keeps it from being lost to the atmosphere.  ");
            _regions.Add(RegionType.ArabiaTerra.Description(), "Land of Many Layers||Scarred by massive numbers of craters and erosion, Arabia is one of the most ancient regions on Mars.  Between the ancient highlands to the south and the more youthful lowlands to the north, the landscape here has been sculpted in layers upon layers of terrain, each a representative a time long gone.  Travel here and you may help reveal Mars' own history of climate change, one layer at a time.  What's of interest here are special clays that form when water soaks the rocks.   They just might be a good place to look for signs of life, either right now or (much more likely) long ago. ");
            _regions.Add(RegionType.ArcadiaPlanitia.Description(), "Utopian Plains||In ancient Greece, Arcadia was a remote place where the people faithfully pursued old customs and folkways, and life retained a simple purity and honesty that had long since vanished from the everyday world. Arcadia thus was a metaphor that embodied a sense of lost innocence.  Arcadian Mars does feature simplicity of a kind: the landscape runs with hardly a bump to the horizon, flat with lava flows and dotted with only a few volcanic cinder cones and impact craters. But, this is no heavenly place...unless maybe you're a microbe.   Arcadia's many craters are surrounded by ramparts of rocky material, suggesting that the ground at the time of the impacts (and perhaps even now) held lots of water at shallow depths. The presence of water, of course, is key to life as we know it.");
            _regions.Add(RegionType.ArgyrePlanitia.Description(), "Mars' Other Big Whack||At the beginning of the solar system some 3.8 billion years ago, Mars took a huge hit.  Like its larger cousin Hellas, the Argyre basin is a giant hole in the ground (about 1100 miles wide and 17,000 feet deep!),  blown out by the impact of an asteroid.  Circular mountain ranges wrap around it, but not all the way!  This basin must have once been full to overflowing, dumping out into a water-carved valley called Uzboi, which just may have traced a meandering course thousands of miles northward to the Chryse's golden plains.  While controversial, if found to be true, you might say that's how gold meets silver on Mars.  Argyre is the mythical land of silver; the glint that's important today is, of course, signs of past water. That's the real treasure here. ");
            _regions.Add(RegionType.ChroniumTerra.Description(), "Plateau of Time ||The Plateau of Time - Planum Chronium - is perfect name for this area of Mars. Unlike Earth's surface, where the geological age averages \"only\" about 250 million years, the Martian surface is far older, with many places dating back nearly to the planet's formation, some 4.5 billion years ago.  We can peer back into our own planet's past by looking at this relatively undisturbed crust, which is a page in a history book scientists have only just begun to read.");
            _regions.Add(RegionType.ChrysePlanitia.Description(), "Plain of Gold||Vikings came to raid this Golden Plain--well, a spacecraft named Viking Lander 1, that is.  Golden Chryse called as a destination because it lies at the end of outflow channels, carved in a time when massive floods raged on Mars.  Since so many channels emptied out here, was it once a large  bay leading to an ancient ocean in the north polar region long ago?  Viking didn't definitively find the \"gold\" it was really seeking:  signs of Martians.  No, not the bug-eyed green-skin kind of science fiction, but maybe, just maybe, tiny life forms called microbes.  Perhaps they're somewhere in this area, hiding, waiting still to be discovered.");
            _regions.Add(RegionType.ElysiumPlanitia.Description(), "Resting Place for Virtuous Heroes||While the giant volcanoes of Tharsis completely steal the show, Mars has another volcanic region called Elysium, the mythological resting place of virtuous heroes.  The biggest hero spending eternity here is a giant volcano called Elysium Mons, stretching about 250 miles wide and 46,000 feet high. Before its demise, hot, highly fluid lavas eroded its flanks, leaving it furrowed with channels.  More numerous channels on the smaller Elysium volcanoes suggest that they're made of softer and more easily eroded ash deposits. On the plains surrounding the main volcanoes, a lot of lava has erupted from long cracks in the Martian surface, creating lava \"rafts\" in repeated flows.  These “rafts” are made of harder material that keeps them more immune to erosion that carries surrounding materials away to a different afterlife.");
            _regions.Add(RegionType.Eridania.Description(), "Impact Debris Stack||Eridania falls on the thick stack of debris thrown out of the Hellas impact basin, created when a large asteroid struck.  Accordingly, it's an old, densely cratered region.  Many craters in Eridania show gullies on their walls, especially on slopes that face generally northward. These appear to have been eroded by water melting from dust-covered deposits of snow and ice left at the time of the last Martian ice ages, hundreds of thousands of years ago.  Scientists have found bands of magnetism with opposing polarties in the rocks of Eridania. Scientists think these were impressed in the rocks during a very early period when Mars had a global magnetic field, which has since vanished for unknown reasons. ");
            _regions.Add(RegionType.HellasPlanitia.Description(), "Largest Visible Crater in the Solar System||No part of Mars went untouched by the Hellas impact in the early days of planet formation in the solar system. Debris thrown out in the impact reached every part of the planet, blanketing it in a global layer of shattered and melted rock that was probably still hot 1,000 years later.  This basin, bright with dust, is the largest surviving impact scar on Mars and the largest visible crater in the solar system.  Roughly half the width of North America and is roughly as deep as Mt. Everest is tall.   Scientists have seen evidence of glaciers and even buried ice at the bottom, as well as lake- or ocean-bottom sediments and volcanic flows. To the east, is cut with valley systems eroded by flowing water, and low volcanic calderas lie nearby.  Go to the bottom and you might even find atmospheric pressure feeling a bit more like that on Earth.");
            _regions.Add(RegionType.HesperiaPlanum.Description(), "Home of the Martian Middle Ages||Hesperia stands in the middle:  in the middle of the southern highlands and in the middle of Martian geologic time. Scientists chose Hesperia Planum to define the middle era in Mars' history, which spans roughly from 3.5 billion years ago until about 1.8 billion years ago. Extensive lava plains spread from several low-elevation volcanos that are moderately cratered.  If Hesperia is the \"Land of the Dawn,\" what arose during the Hesperian age was a lot of volcanic activity.  The giant volcano Olympus Mons in the Tharsis region probably began its ascent during this time.");
            _regions.Add(RegionType.IsidisPlanitia.Description(), "Sagging, Wrinkled Pit||The third largest crater on Mars, this region formed when an asteroid struck long, long ago.  All that's left is an incomplete circle marking the crater's rim.  After impact, though, lava flows from nearby Utopia and Elysium broke past the boundaries and filled it up.  As the shattered ground below Isidis basin sagged under the weight of the lava, it made wrinkles in the surface, much like your palm does when you cup your hand.");
            _regions.Add(RegionType.LunaePlanum.Description(), "Plateau of the Moon||Wearing a crescent moon upon her head, mythical Luna rode on chariot pulled by two powerful horses. If she ever rode over the Martian plain named for her, the terrain would be fairly rough going and she'd have to face a large number of \"ruts\" on a geologic scale.  When you see Plateau of the Moon, it's hard not to think that Mars sprang a leak on the north side of the Mariner Valley. And, actually, that's pretty much what happened.  Volcanoes that built the giant Tharsis bulge made the crust to the east rise up and crack.  Underground water burst out of the Lunae Planum in two main places: Juventae Chasma, and Echus and Hebes Chasma.  Catastrophic floods then carved pathways to the north 1,600 miles long, down to the Golden Plains of Chryse and the vast northern lowlands.");
            _regions.Add(RegionType.MargaritiferTerra.Description(), "A River Ran Through It?||The land here is in chaos!  With entangled cracks and ridges, everything's a jumble.  That's okay, sometimes disorder is a good thing.  In this case, \"chaos terrain\" is a hallmark of subsurface water escaping, causing the surface to collapse.   Water has in fact played a key role in the history of Margaritifer Terra, which stands at the lower end of a channel that extends all the way south to the edge of the Argyre impact basin.  Known as the Uzboi-Ladon-Margaritifer system, it appears to be a connected channel thousands of miles long that could feed water spilling out from Argyre through various craters and valleys all the way north into Chryse Planitita. If the waterway exists - it's controversial - it would offer many places to look for traces of life.  ");
            _regions.Add(RegionType.MeridianiPlanum.Description(), "Land of the Blueberries||You sure can't talk about Meridiani in the abstract anymore, now that the Mars Exploration Rover Opportunity has trekked there, roving farther than any vehicle sent to Mars yet.  When Opportunity landed in a crater known as Eagle, the plucky rover hit a planetary \"hole in one.\"  Almost right away, the rover confirmed the presence of hematite, a round grayish mineral that forms in water and was earlier detected from orbit.  The science team nicknamed the round mineral balls \"blueberries,\" and the rover found continued signs of an ancient, salty, shallow sea.  Was there ever life there? Opportunity doesn't carry life-detection tools, but is working to take the first steps in understanding if this region of Mars could ever have been a home to small life forms known as microbes.");
            _regions.Add(RegionType.NoachisTerra.Description(), "Oldest Terrain on Mars||It's hard to pinpoint the oldest Martian terrain.  Odds are, when found, it'll lie in Noachis Terra’s heavily cratered land.  Scientists chose “Noachian” as the name of the oldest Martian epoch, as the longer a surface is exposed, the more craters it collects.  Noachian time on Mars was eventful. Besides the big impacts (like Hellas and Argyre), volcanic fires started to stir under Tharsis, beginning its uplift.  An abundance of water back then makes Noachis look somewhat softened, as if sediments have been draped over its craters. If Mars had an early warm-and-wet period in the Noachian, life might have started on the Red Planet, paralleling the time when we have the oldest record of life on Earth.");
            _regions.Add(RegionType.PlanumAustrale.Description(), "Home of Geysers||Down Under at the south end of Mars lies the frozen counterpart of the northern ice cap.  It shares the same seasonal cycles as the northern one, but half a Martian year later.  Atop a core of water ice and carbon dioxide ice, and interleaved with layers of dust, lies a thin seasonal ice cap of dry ice that evaporates into the air every spring and reforms every winter.  In the spring, sunlight passes through the thin, semi-transparent layer of dry ice to a sand layer below. The warmed sand evaporates the CO2 from the bottom, creating a layer of pressurized gas. At weak spots in the CO2 ice, the gas breaks through, shooting hundreds of yards into the sky and spraying dust and fine sand in a kind of geyser.");
            _regions.Add(RegionType.PlanumBoreum.Description(), "Where the Air Itself Turns to Ice||Like frosting on a cupcake, the north polar cap dominates Planum Boreum and the top end of Mars.  The ice cap, roughly a thousand miles wide and 10,000 feet thick at its greatest, has a core of water ice coated with a layer of dry ice (frozen carbon dioxide) about a yard thick.  Deep in the northern polar winter night, the air itself becomes cold enough to freeze out on the ground as dry ice. This layer evaporates back into the atmosphere as soon as the northern polar spring begins.  Strong winds and sunlight have cut numerous deep valleys into the ice cap from its edges, making a spiral pattern. Their walls expose layers of ice and dust that show tantalyzing rhythmical structures - a logbook, scientists think, of repeated Ice Ages and cycles of climatic change.");
            _regions.Add(RegionType.PrometheiTerra.Description(), "Land of Prometheus||Punished for bringing fire to humans, mythical Prometheus was tied to a rock without escape, while an eagle ate his liver out day after day. It's a harsh world sometimes, and this heavily cratered land has seen its own hardships.  But, like the Titan for which it is named, perhaps this terrain will this time bring future human explorers water to quench their thirst and power their vehicles and habitats.   Almost literally scratch the surface and touch large reservoirs of glacier ice, snowfall from long ago, easily accessible.    ");
            _regions.Add(RegionType.SolisPlanum.Description(), "Plateau of the Sun||The more you stare at Solis Planum, the less it looks like the rest of Mars.   Stretching 2,000 miles across, this roughly rectangular block is nearly crater-free and smooth, except for a pattern of wrinkle ridges to the east.  Here’s what might have happened.  As Tharsis began to bulge, Solis started to tilt to the east. The ground deep below Solis held lots of water and salt minerals.  While the slope wasn't steep, salt layers deform easily. The top layers slid a little and buckled, making wrinkle ridges.  Tharsis kept rising, and the uplift under Syria Planum cracked open the fissures of Noctis Labrynthus.  Deeper, salt-rich layers under Solis moved southeastward. As the whole block of Solis Planum slid, it raised the Thaumasia ridges, like a hand pushing on a tablecloth. Today, the ridges stand like a humped-up border outlining its edge.  ");
            _regions.Add(RegionType.SyrtisMajor.Description(), "Hourglass Sea||Once named the Hourglass Sea, the dark triangle of Syrtis Major was the first Martian landform ever recorded by an Earth-based astronomer (Christiaan Huygens in 1659). Even now, if you view Mars through a small backyard telescope, chances are Syrtis will be one of the (few) features you can see.  The best telescopic views of Mars don't reveal much, so when  spacecraft went in the 1960s, even the first crude photos showed surprising details.  Lots of craters made Mars look like the Moon, which was a big shock for everyone.  Today, Syrtis Major is known to be a volcano, although it's low and wide unlike the towering giants found in Tharsis. What makes Syrtis look dark is the fact that scouring winds usually blow the light Martian dust away, uncovering the black lava flows that came from its volcanic mouth.");
            _regions.Add(RegionType.TempeTerra.Description(), "Feeling the Strain||Tempe Terra is a furrowed, fractured region on the northeast edge of the giant volcanic region Tharsis. Once glance tells you that even if Tempe isn't a part of Tharsis, it's certainly under its influence. The faults slicing through Tempe all follow the same northeast/southwest trend along which three large Tharsis volcanos have risen.  As the faults formed and became active, the ground between them dropped. This likely released groundwater that carved channels as it flowed northeast toward the lowlands of Acidalia.  Tempe stands on one part of a global boundary between the southern highlands and the northern lowlands. This step-off is a feature that can be traced almost all the way around Mars, but is particularly noticable here. No one knows what caused this abrupt boundary between North and South.");
            _regions.Add(RegionType.TerraCimmeria.Description(), "Where the Spirit Roams||A relatively nondescript and cratered region that sprawls just south of the Martian equator, Terra Cimmeria nonetheless is home to 100-mile-wide Gusev Crater where NASA's Mars Exploration Rover Spirit has spent its roving life.  Scientists originally picked Gusev as a landing spot because it appeared that the crater had once held an ice-covered lake. Lakebed sediments would provide good samples that might preserve evidence of ancient Martian life. It wasn't until Spirit reached the hills and found tantalizing glimpses of the remains of an ancient hot springs, perhaps like those in Yellowstone National Park. ");
            _regions.Add(RegionType.TerraSabaea.Description(), "Impacted Terrain||Atop a thick layer of ejected material from the Hellas impact, the density of craters in Sabaea is roughly as great as in Arabia, making it among the most cratered places on all of Mars. (Noachis Terra just to the south wins top honors in this competition.) A lot of craters here appear partly filled with sediments that might have blown in by the wind. In many cases, this sediment is now being eroded, uncovering the craters' long-buried interior features. To the east and to the north are channels and fractures, many with dunes at the bottom.");
            _regions.Add(RegionType.TerraSirenum.Description(), "Land of the Sirens||Perhaps it's no surprise that this region has magnetic characteristics.  Luring scientists the way the mythical Sirens attracted sailors, this place holds a modern appeal.  This region, in testimony to its age, has rocks with embedded magnetic patterns that scientists think were emplaced early in Mars' history, when the planet had a global magnetic field. For reasons yet to be discovered, this global field vanished billions of years ago.  Sirenum also has deposits of chloride minerals - salts - that lie in depressions and just may preserve traces of any former Martian life that might be present.  How old are these salts and how did they form...and is the place we'll find signs of life?  Can you hear the siren call? ");
            _regions.Add(RegionType.TharsisVolcanicRegion.Description(), "Home to the Solar System's Largest Volcano ||Tharsis would be amazing on any planet, but on a body the size of Mars, it's all the more puzzling. Home to 12 large volcanos, countless smaller ones, and extensive lava flows, Tharsis covers about a quarter of Mars' surface. Its tallest peak, Olympus Mons, reaches an altitude of 70,000 feet and is about as large as Arizona.  The average elevation of Tharsis lies more than 4 miles higher than the average elevation of the Martian surface. Piling up such a huge stack of lava in one place has created a ring-shaped depression of the Martian crust around Tharsis. Why did this one region become the focus for so much volcanic activity? A plume of molten rock rose from deep within Mars and erupted over hundreds of millions of years. Lava accumulated in one region because Mars has no moving crustal plates, unlike Earth. ");
            _regions.Add(RegionType.ThaumasiaPlanum.Description(), "Fractured Land||Thaumasia's long ridge line curves around Solis Planum for over 3,400 miles.  This land is one of the most stressed out, fractured terrains on Mars, created when Solis tilted and rufflied the land during the rise of the great Tharsis bulge. Seen from orbit, networks of branching valleys that look like river channels but were likely caused by rain or snow suggest Mars once might have been warmer and wetter, more Earthlike, in its distant past.");
            _regions.Add(RegionType.TyrrhenaTerra.Description(), "Home to One of Mars' Oldest Volcanoes||Named for a sea between Italy and Sicily, this  heavily cratered terrain makes a home for the giant volcano, Tyrrhena Patera, one of the oldest volcanoes on Mars.  Large troughs called \"fossae\" formed when the land was stretched to the breaking point. Chains of pit craters are also found here, and form when the surface sinks.   One of the rare places on Earth where they can be found, the Hawaiian volcanoes sport some pit craters that can be compared with their Martian cousins.");
            _regions.Add(RegionType.UtopiaPlanitia.Description(), "Ideal Plains of Nowhere ||Utopia became a heavenly home to the Viking 2 Lander when it came to rest on the boulder-strewn Plains of Nowhere.  Why was it so ideal?  It looked like a safe place to land!  Things are still happening in this far-away place, as orbital views show fresh small craters, with ice exposed in the bowl and along their walls!  ");
            _regions.Add(RegionType.VallesMarineris.Description(), "Grandest Canyon in the Solar System||The region of Valles Marineris (or Mariner Valley) contains one of the most striking features humans have ever found in the solar system. The valley is the longest geological scar on Mars, or maybe any planet.  When faulting opened this crack in the crust, it released vast amounts of subterranean water. These floods undermined the valley walls and carried off enough material to leave a canyon as long as North America is wide, and as deep as Mt. Everest is tall. Mariner Valley is far too large to be grasped from ground level. To see it right, you'd need a spaceship with a big window. ");
            _regions.Add(RegionType.VastitasBorealis.Description(), "Bottom of an Ancient Sea?||Wrapped around Mars northern polar ice cap is a giant lowland plain that lies 10,000 feet lower or so than other places on Mars.What produced it? Giant impacts? Possibly. Some kind of tectonic movement? Maybe. Scientists simply don't know.  Perhaps the most exciting possibility  is that it may have been home to one or more giant lakes - or perhaps even an ocean - ages ago. The clue? Beaches! Or at least what appear to be ancient shorelines. It was here in the northern wastelands that the Mars Phoenix Lander set down during summer in the north polar regions of Mars.  Revealing a landscape similar to those in Earths arctic regions, Phoenix was the first to touch water ice by digging only a few inches below the dusty surface.  ");
            _regions.Add(RegionType.XantheTerra.Description(), "Waters of Yore||In the era before spacecraft photos, Xanthe is one area (among many) where Earth-based astronomers once mapped \"canals\" constructed by mythical humanoid \"Martians.\"  To produce these optical illusions, natural features such as channels and dust streaks combined with the human brain's tendency to see - or imagine - patterns in nature.  The real channels found there still hold appeal.   Large outflow channels like Shalbatana Vallis and Ravi Vallis carve paths across the surface. Did water pool in a large lake in Ganges Chasma and work its way north underground, perhaps along geological faults?  As the subterranean water progressed, perhaps it caused the surface above to collapse.  Finally, at some point the water likely broke through to the surface and eroded both into the open channels we see today.");
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            loadDeepZoom();
        }

        private IDictionary<string, string> _initParams = new Dictionary<string, string>();

        string getDesc(string regName)
        {
            string regDesc = _regions[regName];
            return regDesc.Substring(regDesc.IndexOf("||") + 2);
        }

        public string getDesc(RegionType rt)
        {
            string regDesc = _regions[rt.Description()];
            return regDesc.Substring(regDesc.IndexOf("||") + 2);
        }

        void loadDeepZoom()
        {
            DeploymentFactory.Init(_initParams);

            var webClient = new WebClient();
            webClient.DownloadStringCompleted += OnSceneDescriptionLoaded;

            var sceneDescription = DeploymentFactory.Manager.GetDataFileUri(DeploymentFactory.SCENE_XML_FILENAME);
            webClient.DownloadStringAsync(sceneDescription);
        }

        void WebClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            if (e.Error != null || e.Result == null)
            {
                var webClient = sender as WebClient;
                webClient.DownloadStringCompleted += OnSceneDescriptionLoaded;

                var sceneDescription = DeploymentFactory.Manager.GetDataFileUri(DeploymentFactory.SCENE_XML_FILENAME);
                webClient.DownloadStringAsync(sceneDescription);

                return;
            }

            var uri = new Uri(DeploymentFactory.SCENE_XML_FILENAME, UriKind.Relative);
            var zipPackage = new StreamResourceInfo(e.Result, null);
            var sceneResource = Application.GetResourceStream(zipPackage, uri);
            if (sceneResource != null)
            {
                var reader = new StreamReader(sceneResource.Stream);
                CreateAd(reader.ReadToEnd());
            }
        }

        void OnSceneDescriptionLoaded(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Error == null)
                CreateAd(e.Result);
        }

        Ad _ad;
        double adViewerWidth = 655;
        double adViewerHeight = 337;

        private void CreateAd(string xaml)
        {
            if (string.IsNullOrEmpty(xaml))
                return;
            
            _ad = Ad.FromXaml(xaml, _initParams);
            _ad.Viewer.Width = adViewerWidth;
            _ad.Viewer.Height = adViewerHeight;
            _ad.MsiData.Source = new Uri("https://beamdownload.blob.core.windows.net/media/GeneratedImages/dzc_output.xml", UriKind.Absolute); // DeploymentFactory.Manager.GetDeemZoomFileUri();
            cnvMap.Children.Add(_ad.Viewer);
            _ad.Viewer.InitComplete += new RoutedEventHandler(Viewer_Loaded);
            _ad.Viewer.Navigated += new EventHandler(Viewer_Navigated);
            _ad.Viewer.RegionFocused += new EventHandler(Viewer_RegionFocused);

            _ad.Viewer.Init(_ad);
        }

        bool initLoad = true;

        void Viewer_RegionFocused(object sender, EventArgs e)
        {
            if (initLoad)
            {
                int k = 0;
                foreach (MultiScaleSubImage img in msiMap.SubImages)
                {
                    if (k < msiMap.SubImages.Count - 2)
                    {
                        img.Opacity = 0;
                        img.ZIndex = 5;
                    }

                    k++;
                }
                initLoad = false;
            }

            string curTitle = ((AdItem)sender).Title.Replace("Thumb", "").Trim();

            if (_selectedRegion.Description() == curTitle)
                return;

            if (selectedSubImage != null)
                selectedSubImage.Opacity = 0;

            int highlightedRegion = (int)Enum.Parse(typeof(RegionType), stripRegion(curTitle), true);
            if (msiMap.SubImages.Count == 0 || highlightedRegion < 0)
                return;

            selectedSubImage = msiMap.SubImages[highlightedRegion];

            selectedSubImage.Opacity = 0.4;
            setSelectedLocation(sender, false);
        }

        MultiScaleSubImage selectedSubImage;

        string stripRegion(string val, bool removeInnerSpaces)
        {
            string ret = val;
            foreach (char c in val.ToCharArray())
            {
                if (Char.IsNumber(c))
                    ret = ret.Replace(c, ' ');
            }
            if (removeInnerSpaces)
                return ret.Replace(" ", "").Replace("Thumb", "");
            else
                return ret.Replace("Thumb", "").Trim();
        }

        string stripRegion(string val)
        {
            return stripRegion(val, true);
        }

        void Viewer_Navigated(object sender, EventArgs e)
        {
            string regName = "";

            if (typeof(AdItem).Equals(sender.GetType()))
                regName = ((AdItem)sender).Title;
            else
                regName = ((ContentControl)sender).Content.ToString();

            FocusRegion(sender);
        }

        void FocusRegion(object sender)
        {
            string regName = "";

            if (typeof(AdItem).Equals(sender.GetType()))
                regName = ((AdItem)sender).Title;
            //else if (typeof(Location).Equals(sender.GetType()))
            //    regName = ((Location)sender).Name;
            else
                regName = ((ContentControl)sender).Content.ToString();

            if (selectedSubImage != null)
                selectedSubImage.Opacity = 0;

            int highlightedRegion = (int)Enum.Parse(typeof(RegionType), stripRegion(regName), true);

            if (highlightedRegion < 0)
                return;

            selectedSubImage = msiMap.SubImages[highlightedRegion];
            selectedSubImage.Opacity = 0.4;
            RegionHoverEffect(highlightedRegion);
            setSelectedLocation(sender, true);
        }

        void RegionHoverEffect(int regionID)
        {
            msiMap.SubImages[regionID].Opacity = 1;
            Storyboard sb = new Storyboard();
            DoubleAnimation db = new DoubleAnimation();
            db.To = 0.2;
            db.Duration = TimeSpan.FromMilliseconds(500);
            sb.Duration = TimeSpan.FromMilliseconds(500);
            sb.Children.Add(db);

            Storyboard.SetTarget(db, msiMap.SubImages[regionID]);
            Storyboard.SetTargetProperty(db, new PropertyPath("(UIElement.Opacity)"));

            //sb.Stop();
            //sb.AutoReverse = true;
            sb.Begin();
        }

        void setSelectedLocation(object sender, bool showEventDetails)
        {
            string regName = "";

            if (typeof(AdItem).Equals(sender.GetType()))
                regName = ((AdItem)sender).Title;
            //else if (typeof(Location).Equals(sender.GetType()))
            //    regName = ((Location)sender).Name;
            else
                regName = ((ContentControl)sender).Content.ToString();

            regName = stripRegion(regName, false);
            string regDesc = _regions[regName];

            if (regName != null && regName.Length > 0)
            {
                RegionType loc = (RegionType)Enum.Parse(typeof(RegionType), regName.Replace(" ", ""), true);
                _locationInfo.Show(loc, this);

                if (showEventDetails)
                {
                    _selectedRegion = loc;
                    _eventInfo.Text = getDesc(_selectedRegion);

                    //((Storyboard)Resources["BeamSwitchOn"]).Stop();
                    //((Storyboard)Resources["BeamSwitchOn"]).Begin();
                    //_eventInfo.Show();
                }
            }
        }

        MultiScaleImage msiMap;

        void Viewer_Loaded(object sender, RoutedEventArgs e)
        {
            msiMap = _ad.Viewer.MainImage.MSImage;
            msiMap.ViewportWidth = 0.7;
            msiMap.ViewportOrigin = new Point(0.18572394879014029, 0.02992912761118691);

            Locations = new Dictionary<UIElement, Point>();

            msiMap.UseSprings = true;
            msiMap.ViewportChanged += new RoutedEventHandler(MultiScaleImage_ViewportChanged);
            msiMap.ImageOpenSucceeded += new RoutedEventHandler(msiMap_ImageOpenSucceeded);
            msiMap.ImageOpenFailed += new EventHandler<ExceptionRoutedEventArgs>(msiMap_ImageOpenFailed);
            msiMap.MotionFinished += new RoutedEventHandler(msiMap_MotionFinished);
        }

        void msiMap_ImageOpenFailed(object sender, ExceptionRoutedEventArgs e)
        {
            throw new NotImplementedException();
        }

        void msiMap_MotionFinished(object sender, RoutedEventArgs e)
        {
            Refresh();
        }
        void msiMap_ImageOpenSucceeded(object sender, RoutedEventArgs e)
        {
            msiMap.Width = cnvMap.Width;
            msiMap.Height = cnvMap.Height;
            Refresh();
            chShowTitles.IsEnabled = true;
            pbProgress.IsIndeterminate = false;
            pbProgress.Visibility = System.Windows.Visibility.Collapsed;
        }

        public void ToggleMap(bool mapOn)
        {
            if (mapOn)
            {
                spContent.Children[0].Visibility = Visibility.Collapsed;

                for (int i = 1; i < spContent.Children.Count; i++)
                {
                    spContent.Children[i].Visibility = Visibility.Visible;
                }
            }
        }

        public void Zoom(double zoom, Point pointToZoom)
        {
            Point logicalPoint = msiMap.ElementToLogicalPoint(pointToZoom);
            msiMap.ZoomAboutLogicalPoint(zoom, logicalPoint.X, logicalPoint.Y);
        }


        private void Refresh()
        {
            foreach (UIElement i in grdLayer1.Children)
            {
                TransformGroup transformFinal = new TransformGroup();
                transformFinal.Children.Add(new ScaleTransform() { ScaleX = 1.0 / msiMap.ViewportWidth, ScaleY = 1.0 / msiMap.ViewportWidth });
                transformFinal.Children.Add(ProjectedTranslateTransform(Locations[i]));
                i.RenderTransform = transformFinal;
            }
        }
        private Dictionary<UIElement, Point> Locations;

        // Function that converts relative location(0.0 left-top, 1.0 bottom-right) to 
        // actual location depending on MultiScaleImage's ViewportWidth, and ViewportOrigin.
        private TranslateTransform ProjectedTranslateTransform(Point value)
        {
            if (msiMap.SubImages.Count > 0)

                //TODO: check both .Width and .ViewPortWidth in debugger
                return new TranslateTransform()
                {
                    X = (msiMap.Width * value.X - msiMap.Width * msiMap.ViewportOrigin.X)
                        / msiMap.ViewportWidth,
                    Y = ((msiMap.Width / msiMap.SubImages[0].AspectRatio)
                        * value.Y - msiMap.Width * msiMap.ViewportOrigin.Y)
                        / msiMap.ViewportWidth
                };

            else
                return null;
        }

        void MultiScaleImage_ViewportChanged(object sender, RoutedEventArgs e)
        {
            Refresh();
        }
        
        public void FadeOut(Image img)
        {
            if (img == null) return;
            Storyboard sb = new Storyboard();
            DoubleAnimation db = new DoubleAnimation();
            db.To = 0; // From 100% opaque to 0% opaque
            db.Duration = TimeSpan.FromMilliseconds(500);
            sb.Duration = TimeSpan.FromMilliseconds(500);
            sb.Children.Add(db);

            Storyboard.SetTarget(db, img);
            Storyboard.SetTargetProperty(db, new PropertyPath("(UIElement.Opacity)"));

            sb.Stop();
            sb.Begin();
        }

        public void FadeIn(Image img)
        {
            if (img.Opacity == 1)
                return;

            Storyboard sb = new Storyboard();
            DoubleAnimation db = new DoubleAnimation();
            db.To = 1; // From 100% opaque to 0% opaque
            db.Duration = TimeSpan.FromMilliseconds(500);
            sb.Duration = TimeSpan.FromMilliseconds(500);
            sb.Children.Add(db);

            Storyboard.SetTarget(db, img);
            Storyboard.SetTargetProperty(db, new PropertyPath("(UIElement.Opacity)"));

            sb.Stop();
            sb.Begin();
        }

        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            msiMap.SubImages[31].ZIndex = 3;
        }

        private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
        {
            msiMap.SubImages[31].ZIndex = -1;
        }

        void stretchControl(FrameworkElement fe)
        {
            fe.Width = double.NaN;
            fe.Height = double.NaN;
            fe.HorizontalAlignment = HorizontalAlignment.Stretch;
            fe.VerticalAlignment = VerticalAlignment.Stretch;
        }

        private void abZoomOut_Click(object sender, EventArgs e)
        {
            Zoom(0.5, new Point(240, 300));
        }

        private void abZoomIn_Click(object sender, EventArgs e)
        {
            Zoom(2, new Point(240, 300));
        }

    }

    static class extMethods
    {
        public static string Description(this System.Enum value)
        {
            Type type = value.GetType();
            MemberInfo[] memInfo = type.GetMember(value.ToString());

            if (memInfo != null && memInfo.Length > 0)
            {
                object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);

                if (attrs != null && attrs.Length > 0)
                    return ((DescriptionAttribute)(attrs[0])).Description;
            }

            return value.ToString();
        }

    }

}
